import ErrorBoundaryCustom from '@/components/ErrorBoundaryCustom';
import {
  PErrCustom,
  PLoadingCustom,
  CTabbarCustom,
  CWechatLoginCustom,
  CLoadMoreCustom,
  CDialogCustom,
  CSelectCustom,
  CCalendarCustom,
  CDatetimePickerVantCustom,
  CCascaderCustom,
} from '@vh-mobile/pro-components';
import { useAppDataDoneModel } from '@/models/useGlobalModel';
import { useUserModel } from '@/models/useUserModel';
import {
  useReady,
  useDidShow,
  useDidHide,
  usePullDownRefresh,
  useReachBottom,
  useRouter,
  useResize,
} from '@tarojs/taro';
import { useState, useEffect, useMemo, useImperativeHandle, useRef } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { getOpenId, setToken } from '@/utils/storage';
import { onNetworkStatusChange, getEnv } from '@tarojs/taro';
import { eventsBus, redirectTo, switchTab } from '@vh-mobile/pro-utils';
import { TabbarColumns } from './define';
import { View } from '@tarojs/components';
import styles from './index.module.less';
import { miniprogramLogin } from '@/services/public/miniprogram';
import useLoadMore from '@/hooks/useLoadMore';
import { checkPermissionAuth } from '../../access';
import { useDeepCompareEffect } from 'ahooks';
import { offNetworkStatusChange } from '@tarojs/taro';
import global from '@/utils/globalUtils';
import { pxTransform } from '@tarojs/taro';
import { authIsLogin } from '@/services/public/user';
// import { share } from '@/utils/wechat';

export declare type pageErrorItemType = {
  /**
   * 可选显示的状态值
   */
  status: 'RequestError' | 'JsError' | 'BoundaryError' | 'NotFind' | 'NotAuth' | 'NotNetwork';
  /**
   * 错误信息
   */
  message?: string;
  /**
   * 错误的code
   */
  code?: number | string;
};

export declare type pageErrorType = pageErrorItemType | undefined;

export declare type MainRefType = {
  /**
   * 设置pageLoading显示状态
   */
  setPageLoading: (loading: boolean) => void;
  /**
   * 显示登录弹窗
   */
  setShowLogin: (login: boolean) => void;
  /**
   * 重置分页数据和状态
   */
  setLoadMoreReset: () => void;
  /**
   * 刷新当前页面数据
   * 是否清空当前页面的数据
   * clearData 默认 true
   */
  setRefreshResetData: (clearData?: boolean) => void;
};

export declare type SummaryType = {
  /**
   * '合计'显示赋值字段
   */
  field?: string;
  /**
   * 显示的文字
   * @default '合计'
   */
  text?: string;
};

export declare type MainContainerCustomType = {
  /**
   * 显示的内容
   */
  children: any;
  /**
   * pageLoading的默认显示状态
   * @default true
   */
  defaultPageLoading?: boolean;
  /**
   * 是否显示tabbar
   * @default false
   */
  showTabbar?: boolean;
  /**
   * 被选中的tabbar
   */
  tabbarActive?: string | number;
  /**
   * 修改一些状态的ref
   */
  mainRef?: React.MutableRefObject<MainRefType | undefined>;
  /**
   * 页面是否需要登录
   */
  login?: boolean;
  /**
   * 登录的是否使用全屏模式
   * @default false
   */
  loginFullScreen?: boolean;
  /**
   *  是否开启加载更多
   */
  loadMore?: boolean;
  /**
   *  分页数据
   */
  loadData?: any;
  /**
   * 触发onshow时是否刷新当前数据
   */
  onShowRequest?: boolean;
  /**
   *  设置分页数据的状态
   */
  setLoadData?: any;
  /**
   * 请求分页数据的方法
   */
  loadRequest?: (params: any) => Promise<any>;
  /**
   * 发起请求前参数钩子
   * @param params
   */
  requestBefor?: (params: any) => any;
  /**
   * 进入页面是否自动发起请求
   * @default true
   */
  loadRequestFirst?: boolean;
  /**
   * 请求的参数 参数变化分页刷新
   * @default {}
   */
  loadRequestParams?: any;
  /**
   * 是否开启了下拉刷新
   */
  enablePullDownRefresh?: boolean;
  /**
   * 分页条数
   * @default 20
   */
  pageSize?: number;
  /**
   * 页面需要的显示的权限ID
   */
  accessId?: number | string;
  /**
   * 显示'合计'字符串的赋值字段
   * @default name
   */
  /**
   * 显示合计字段
   * 默认 不开启
   */
  summary?: SummaryType | boolean;

  /**
   * 底部留白 像素
   */
  bottomBlank?: number;
};

function MainContainerCustom(props: MainContainerCustomType) {
  const {
    defaultPageLoading = true,
    mainRef,
    showTabbar = false,
    tabbarActive,
    login = false,
    loadMore = false,
    loadData = [],
    onShowRequest = false,
    setLoadData,
    loadRequest,
    requestBefor,
    loadRequestFirst = true,
    loadRequestParams = {},
    enablePullDownRefresh = false,
    loginFullScreen = false,
    pageSize = 20,
    accessId,
    summary,
    bottomBlank,
  } = props;
  const isLoadFirst = useRef<boolean>(false);
  const appDataDoneModel = useRecoilValue(useAppDataDoneModel);
  const [pageLoading, setPageLoading] = useState<boolean>(() => {
    if (appDataDoneModel) {
      return false;
    }
    return defaultPageLoading;
  });
  const [pageError, setPageError] = useState<pageErrorType>();
  const [showLogin, setShowLogin] = useState<boolean>(false);
  const [userModel, setUserModel] = useRecoilState(useUserModel);
  const [mainLoadData, setMainLoadData] = useState<any>([]);
  const mainLoadDataRef = useRef<any>([]);
  const loadRequestParamsRef = useRef<any>({});

  const {
    loadMoreState,
    loadMoreShowLoading,
    loadMoreHideLoading,
    loadMoreCheckLoading,
    loadMoreLoadHandle,
    loadMoreReset,
    loadMoreDone,
  } = useLoadMore();

  const router = useRouter();

  const setMainLoadDataConfig = (datas: any) => {
    mainLoadDataRef.current = datas;
    setLoadData(datas);
    setMainLoadData(datas);
  };

  // 清空数据
  const loadRequestReset = (clearData: boolean = true) => {
    loadMoreReset();
    if (clearData) {
      // 在小程序中如果不开启清空数据，列表会因为key相同而显示错乱
      setMainLoadDataConfig([]);
    }
  };

  //初始化配置data
  useEffect(() => {
    setMainLoadData([...loadData]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 分页的处理逻辑
  const loadRequestData = (type: any, page?: number) => {
    if (type && typeof loadRequest === 'function' && setLoadData) {
      if (!loadMoreCheckLoading(!!page)) {
        return false;
      }
      loadMoreShowLoading();

      let params: any = {
        page: page || loadMoreState.page,
        pageSize: pageSize,
        ...loadRequestParamsRef.current,
      };

      // 如果携带有分页排序则处理
      if (params.pageSort && params.pageSort.indexOf('-') !== -1) {
        const orderArr = params.pageSort.split('-');
        params.field = orderArr[0];
        params.order = orderArr[1];
      }

      if (!params.pageSort) {
        params.pageSort = undefined;
      }

      if (requestBefor) {
        params = requestBefor(params);
      }

      loadRequest(params)
        .then((res: any) => {
          let datas: any = [];
          if (res.data.summary && summary && mainLoadDataRef.current.length === 0) {
            let field: any = 'name';
            let text: any = '合计';
            if (typeof summary !== 'boolean') {
              if (summary.field) {
                field = summary.field;
              }
              if (summary.text) {
                text = summary.text;
              }
            }
            datas.push({ ...res.data.summary, [field]: text, id: text });
          }
          //如果是重置页码清空之前数据
          if (page) {
            datas = [...datas, ...res.data.data];
          } else {
            datas = [...datas, ...mainLoadDataRef.current, ...res.data.data];
          }
          // datas = [...datas, ...mainLoadDataRef.current, ...res.data.list];
          setMainLoadDataConfig(datas);
          loadMoreLoadHandle(res.data.total, datas.length);
        })
        .catch(() => {
          loadMoreDone();
        })
        .finally(() => {
          loadMoreHideLoading();
        });
    }
  };

  // 请求参数变化后指定发起请求
  useDeepCompareEffect(() => {
    loadRequestParamsRef.current = loadRequestParams;
    if (loadRequest && loadMore && appDataDoneModel && isLoadFirst.current === true) {
      loadRequestReset();
      loadRequestData('loadRequestParams', 1);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [loadRequestParams]);

  // 请求参数变化后指定发起请求
  useEffect(() => {
    if (loadRequest && loadMore && appDataDoneModel && loadRequestFirst) {
      loadRequestReset();
      loadRequestData('loadRequestApi', 1);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [loadRequest]);

  //如果配置了自动发起类表请求
  useEffect(() => {
    if (loadRequest && loadMore && appDataDoneModel && loadRequestFirst) {
      loadRequestData('appDataDoneModel', 1);
    }
    // 完成第一次加载
    if (!isLoadFirst.current) {
      isLoadFirst.current = true;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [appDataDoneModel]);

  // // for react-refresh 重置状态
  // useEffect(() => {
  //   isLoadFirst.current = false;
  // }, []);

  const refreshResetData = (clearData: boolean = true) => {
    loadRequestReset(clearData);
    setTimeout(() => {
      loadRequestData('refreshResetData', 1);
    }, 100);
  };

  useImperativeHandle(
    mainRef,
    () => {
      return {
        setPageLoading: (loading: boolean) => {
          setPageLoading(loading);
        },
        setShowLogin: (show: boolean) => {
          setShowLogin(show);
        },
        setLoadMoreReset: () => {
          loadRequestReset();
        },
        setRefreshResetData: (clearData: boolean = true) => {
          refreshResetData(clearData);
        },
      };
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [],
  );

  useEffect(() => {
    if (getEnv() === 'WEAPP') {
      global.log(getOpenId());
    }
    // 设置监听页面错误事件
    eventsBus.$pageOn('SetPageError', (data: pageErrorType) => {
      setPageError(data);
    });
    // 设置监听页面登录弹窗
    eventsBus.$pageOn('SetShowLogin', (show: boolean) => {
      setShowLogin(show);
    });

    onNetworkStatusChange((res: any) => {
      if (!res.isConnected) {
        setPageError({
          status: 'NotNetwork',
        });
      }
    });
    return () => {
      offNetworkStatusChange();
      eventsBus.$pageOff('SetPageError', router.path);
    };

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // useEffect(() => {
  //   // 如果需要登录并调用验证
  //   if (login) {
  //     eventsBus.$trigger('GlobalEvents', { type: 'checkLogin' });
  //   }
  //   // eslint-disable-next-line react-hooks/exhaustive-deps
  // }, []);

  useEffect(() => {
    // 如果必要数据都加载完毕
    if (appDataDoneModel) {
      setPageLoading(false);
      // 如果是微信H5 可以开启自定义分享
      // if(autoShare){
      //   share();
      // }
    }
  }, [appDataDoneModel]);

  useEffect(() => {
    // 如果有用户数据并且有权限限制
    if (userModel && accessId) {
      if (!checkPermissionAuth(userModel, accessId)) {
        setPageError({
          status: 'NotAuth',
          message: '没有权限',
          code: 403,
        });
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userModel]);

  useReady(() => {
    global.log('useReady');
  });

  useDidShow(() => {
    if (onShowRequest) {
      refreshResetData(false);
    }
    global.log('useDidShow', router);
  });

  useDidHide(() => {
    global.log('useDidHide');
  });

  usePullDownRefresh(() => {
    if (enablePullDownRefresh) {
      refreshResetData();
    }
    global.log('usePullDownRefresh');
  });

  useReachBottom(() => {
    if (loadMore) {
      loadRequestData('useReachBottom');
    }
    global.log('useReachBottom');
  });

  // usePageScroll((payload: PageScrollObject) => {
  //   global.log('usePageScroll', payload);
  // });

  useResize(() => {
    global.log('useResize');
  });

  // 微信弹窗登录
  const wechatLogin = async (userProfile: any) => {
    try {
      const res: any = await miniprogramLogin({
        iv: userProfile.iv,
        encryptedData: userProfile.encryptedData,
      });
      setToken(res.data.token);
      setUserModel(res.data.user);
      setShowLogin(false);
      return true;
    } catch (error) {
      return false;
    }
  };

  // 刷新页面
  const goBack = () => {
    // // 更新用户信息
    // authIsLogin()
    //   .then((res: any) => {
    //     setUserModel(res.data);
    //   })
    //   .catch(() => {});

    switchTab({
      url: '/pages/index/index',
    });

    // const hasTabBar: any = tabBarList.filter((i: any) => router.path.indexOf(i.pagePath) !== -1);

    // if (hasTabBar.length > 0) {
    //   switchTab({
    //     url: router.path,
    //   });
    // } else {
    //   redirectTo({
    //     url: router.path,
    //   });
    // }
  };

  const tabbarOnClick = (item: any) => {
    // switchTab({
    //   url: item.pages,
    // });

    redirectTo({
      url: item.pages,
    });
  };

  //可以设置很多中公用错误展示
  const pageErrorNode = useMemo(() => {
    return (
      <>
        {pageError?.status === 'RequestError' ? (
          <PErrCustom onClick={goBack} bntText="去首页" />
        ) : pageError?.status === 'BoundaryError' ? (
          <PErrCustom onClick={goBack} bntText="去首页" description="页面崩溃了亲o(╥﹏╥)o" />
        ) : pageError?.status === 'NotFind' ? (
          <PErrCustom onClick={goBack} bntText="去首页" description="页面走丢了o(╥﹏╥)o" />
        ) : pageError?.status === 'NotAuth' ? (
          <PErrCustom onClick={goBack} bntText="去首页" description="你的权限不够哦(*╹▽╹*)" />
        ) : (
          <PErrCustom
            onClick={goBack}
            bntText="去首页"
            description="未知错误、刷新页面或者联系管理吧(*^▽^*)"
          />
        )}
      </>
    );
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pageError]);

  const tabbarNode = useMemo(() => {
    return (
      <CTabbarCustom
        columns={TabbarColumns}
        active={tabbarActive}
        inactiveColor="#8E8E93"
        onClick={tabbarOnClick}
      />
    );
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const wechatLoginCustomNode = (
    <>
      <CWechatLoginCustom
        login={wechatLogin}
        modelClick={() => setShowLogin(false)}
        fullScreen={loginFullScreen}
      />
    </>
  );

  const commonNode = useMemo(() => {
    return (
      <>
        {/* 公用确认信息弹窗使用 */}
        <CDialogCustom />
        {/* 公用select选择 */}
        <CSelectCustom options={[]} value={undefined} onChange={() => {}} />
        {/* 公用DatetimePicker选择 2.0.1 版本增加  */}
        <CDatetimePickerVantCustom value={undefined} onChange={() => {}} />
        {/* 公用Calendar  */}
        <CCalendarCustom value={undefined} onChange={() => {}} />
        {/* 公用cascader  */}
        <CCascaderCustom value={undefined} onChange={() => {}} />
      </>
    );
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const pLoadingCustomNode = <PLoadingCustom />;

  return (
    <ErrorBoundaryCustom>
      <PErrCustom
        className={pageError?.status === 'NotNetwork' ? styles.notNetwork : styles.noneNetwork}
        onClick={goBack}
        bntText="刷新"
        description="网络崩溃了亲o(╥﹏╥)o"
        image="network"
      />
      {commonNode}
      {/* 页面错误处理显示 */}
      {pageError && pageError?.status !== 'NotNetwork' && pageErrorNode}
      {/* 如果页面主要数据没有加载完毕的loading状态 */}
      {!pageError && pageLoading && pLoadingCustomNode}
      {/* 显示的页面 */}
      {!pageError && !pageLoading && (
        <>
          {/* 微信登录弹窗 */}
          {getEnv() === 'WEAPP' &&
            !userModel &&
            (login === true || showLogin === true) &&
            wechatLoginCustomNode}
          {/* 如果开启了显示Tabbar */}
          {showTabbar && tabbarNode}
          {props.children}
          {loadMore && loadMoreState.isStart && (
            <CLoadMoreCustom data={mainLoadData} loadMoreState={loadMoreState} />
          )}
          {/* 底部留白 */}
          {bottomBlank && <View style={{ height: pxTransform(bottomBlank) }}> </View>}
          {/* 固定一个高度撑开底部 */}
          {showTabbar && <View className={styles.tabbarBlack}> </View>}
        </>
      )}
    </ErrorBoundaryCustom>
  );
}

export default MainContainerCustom;
